package com.yzf.smsforward;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.yzf.smsforward.Constants.TAG;

/**
 * 项目名称：FoldingVerifyCode
 * 类描述：短信内容解析类
 * 创建人：Administrator
 * 创建时间：2019年10月1日
 */
public class SimUtils {

    public static JSONArray getAllSimInfo(TelephonyManager tel) throws NoSuchMethodException, JSONException {

        Class<?> clazz = tel.getClass();

        //获取可以进行反射的字段
        List<EMethod> list = new ArrayList<>();
        Map<String, Integer> listIgnore = new HashMap<>();

        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            String name = method.getName();
            if (!name.startsWith("get"))
                continue;

            if (listIgnore.get(name) != null)
                continue;
            listIgnore.put(name, 0);

            Method m1 = null;
            Method m2 = null;
            Method m3 = null;
            try {
                m1 = clazz.getDeclaredMethod(name);
            } catch (Exception e) {
            }
            try {
                m2 = clazz.getDeclaredMethod(name, int.class);
            } catch (Exception e) {
            }
            try {
                m3 = clazz.getDeclaredMethod(name, long.class);
            } catch (Exception e) {
            }

            if (m1 != null && ((m2 == null && m3 != null) || (m2 != null && m3 == null))) {
                Class<?> c1 = m1.getReturnType();
                Class<?> c2 = m2 == null ? null : m2.getReturnType();
                Class<?> c3 = m3 == null ? null : m3.getReturnType();
                if (m2 == null) {
                    if (c1 == null || c1 != c3)
                        continue;
                } else {
                    if (c1 == null || c1 != c2)
                        continue;
                }
                EMethod item = new EMethod(name, m2 == null ? 1 : 0, c1);
                list.add(item);
            }
        }
        listIgnore.clear();

        JSONArray array = new JSONArray();
        for (int i = 0; i < 10; i++) {
            JSONObject json = new JSONObject();
            for (EMethod em : list) {
                Method method = null;
                Object param = null;
                if (em.type == 0) {
                    method = clazz.getDeclaredMethod(em.name, int.class);
                    param = i;
                } else {
                    method = clazz.getDeclaredMethod(em.name, long.class);
                    param = new Long(i);
                }
                if (!method.isAccessible())
                    method.setAccessible(true);

                String name = em.name.substring(3);
                Object value = null;
                try {
                    value = method.invoke(tel, param);
                } catch (Exception e) {
                    //前面已经对private设置了可访问，有些还是会报错，就不管这个了
                    continue;
                }

                json.put(name, value);
            }

            if (json.optInt("SimState") == TelephonyManager.SIM_STATE_UNKNOWN || json.optInt("SimState") == TelephonyManager.SIM_STATE_ABSENT)
                continue;

            String imsi = json.optString("SubscriberId");
            if (imsi == null || imsi.length() == 0)
                continue;

            //根据imsi去重
            boolean repeact = false;
            for (int j = 0; j < array.length(); j++) {
                if (imsi.equals(array.optJSONObject(j).optString("SubscriberId"))) {
                    repeact = true;
                    break;
                }
            }
            if (repeact)
                continue;

            array.put(json);
        }
        return array;
    }

    static class EMethod {
        public String name;
        public int type;    //0为int，1为long
        public Class<?> returnType;    //返回类型

        public EMethod(String name, int type, Class<?> returnType) {
            this.name = name;
            this.type = type;
            this.returnType = returnType;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
    public static JSONArray getSimInfoBySubscriptionManager(Context context) {
        JSONArray array = new JSONArray();
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            return array;
        }
        List<SubscriptionInfo> list = SubscriptionManager.from(context).getActiveSubscriptionInfoList();
        if (list != null) {
            for (SubscriptionInfo info : list) {
                JSONObject json = new JSONObject();

                Log.d(TAG,  "info-->" + info.toString());
                Log.d(TAG,  "ICCID-->" + info.getIccId());
                Log.d(TAG,  "Number-->" + info.getNumber());
                Log.d(TAG,  "subId-->" + info.getSubscriptionId());
                Log.d(TAG,  "DisplayName-->" + info.getDisplayName());
                Log.d(TAG,  "CarrierName-->" + info.getCarrierName());
                Log.d(TAG,  "---------------------------------");
                try {
                    json.put(com.yzf.smsforward.Constants.SUBSCRIBER_ID, info.getIccId());
                    json.put(com.yzf.smsforward.Constants.LINE1NUMBER, info.getNumber());
                    json.put(com.yzf.smsforward.Constants.SIMSLOTINDEX, info.getSimSlotIndex());
                    json.put(com.yzf.smsforward.Constants.SUBID, info.getSubscriptionId());
                    json.put(com.yzf.smsforward.Constants.SIMINFO, info.toString());
                    json.put(com.yzf.smsforward.Constants.CARRIERNAME, info.getCarrierName());
                    json.put(com.yzf.smsforward.Constants.DISPLAYNAME, info.getDisplayName());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                array.put(json);
            }
        }

        return array;
    }

    /**
     * @param slotId  slotId为卡槽Id，它的值为 0、1；
     * @return
     */
    public static String getIMEI(Context context, int slotId) {
        try {
            TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Method method = manager.getClass().getMethod("getImei", int.class);
            String imei = (String) method.invoke(manager, slotId);
            return imei;
        } catch (Exception e) {
            return "";
        }
    }

    public static String getIMEI(Context context) {
        try {
            TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Class<?> telephonyClass;
            Object result = null;
            Object result0 = null;
            Object result1 = null;
            try {
                telephonyClass = Class.forName(telephony.getClass().getName());
                Method m1 = telephonyClass.getMethod("getSubscriberId");
                Method m2 = telephonyClass.getMethod("getSubscriberId", new Class[]{int.class});
                result = m1.invoke(telephony);
                result0 = m2.invoke(telephony, 0);
                result1 = m2.invoke(telephony, 1);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return "";
            }
            Log.i(TAG, " --------------getSubscriberId-------------- : " + telephony.getSubscriberId() + "\n"
                    + " result : " + result + "\n"
                    + " result0 : " + result0 + "\n"
                    + " result1 : " + result1 + "\n");

        } catch (Exception e) {
            return "";
        }
        return "";
    }
}
